<template>
  <div class="treeNodeWrap">
    <div class="handleToggle">
      <i
        v-if="hasChildren"
        class="iconfont icon-sanjiaoright"
        :class="[isOpen ? 'rotate' : '']"
        @click="fnToggle"
      />
      <!-- S check样式  -->
      <div v-if="treeType == 'check'" class="wrapCheck" @click="fnCheck">
        <i
          class="iconfont icon-choice-full checkIcon"
          v-if="dataChild['type'] == 'full'"
        ></i>
        <i
          class="iconfont icon-weiquanxuan checkIcon"
          v-if="dataChild['type'] == 'half'"
        ></i>
      </div>
      <!-- E check样式  -->
    </div>

    {{ dataChild.label }}
    <hTransition>
      <TreeNode
        v-if="Array.isArray(dataChild.children) && isOpen"
        v-for="items in dataChild.children"
        :key="items.id"
        :data="items"
      />
    </hTransition>
  </div>
</template>
<script>
// import TreeCheck from "./TreeCheck.vue";
import hTransition from "./hTransition.vue";
export default {
  name: "TreeNode",
  inject: ["Tree"],
  props: {
    data: Object,
    dataAll: Array,
  },
  data() {
    return {
      isOpen: false,
      type: "",
      isCheck: false,
      dataChild: {},
    };
  },
  components: {
    hTransition,
    // TreeCheck,
  },
  computed: {
    // 判断是否有子集
    hasChildren() {
      return Array.isArray(this.data.children) && this.data.children.length > 0;
    },

    // 判断样式
    treeType() {
      return this.Tree.treeType || "default";
    },

    // 将数组转换成字符串
    dataAllToStr() {
      return JSON.stringify(this.dataAll);
    },

    children() {
      return this.dataChild.children || [];
    },
  },
  mounted() {
    this.dataChild = this.data;
  },
  methods: {
    //展开关闭
    fnToggle() {
      this.isOpen = !this.isOpen;
    },


    /*
    * 点击选中与取消
    * */
    fnCheck() {
//      this.$set(this.data, "type", "full");
//      this.$set(this.data, "isCheck", true);
      if (this.dataChild.isCheck) {
        this.$set(this.dataChild, "isCheck", false);
        this.$set(this.dataChild, "type", "no");
        this.fnCheckChildren(false)
        // this.data.isCheck = false;
      } else {
        this.$set(this.dataChild, "type", "full");
        this.$set(this.dataChild, "isCheck", true);
        this.fnCheckChildren(true)
        // this.data.isCheck = true;
      }

    },

    /*
    * 点击父级·保证子级选中与取消
    * */
    fnCheckChildren(flag){
      let children = this.dataChild.children
      this.isCheckFn(children, flag)
    },

    /*
    * 递归遍历，保证选中与取消
    * */
    isCheckFn(arr, flag){
      if (Array.isArray(arr) && arr.length > 0) {
        for (let i = 0; i < arr.length; i++) {
          let item = arr[i]
          this.$set(arr[i], "isCheck", flag);
          if(flag == true){
            this.$set(arr[i], "type", "full");
          }
          else{
            this.$set(arr[i], "type", "no");
          }
          this.isCheckFn(item.children, flag)
        }

      }
    },

    /*
    * 通过递归遍历所有数据，来计算选中与取消
    * */
    isAllCheck(arr) {
      if (Array.isArray(arr) && arr.length > 0) {
        for (let i = 0; i < arr.length; i++) {
          let children = arr[i]["children"];
          if (Array.isArray(children) && children.length > 0) {
            let flagEvery = children.every((item) => item.isCheck);
            let flagSome = children.some(
              (item) => item.isCheck || item.type == "half"
            );
            if (flagEvery) {
              this.$set(arr[i], "isCheck", true);
              this.$set(arr[i], "type", "full");
            } else if (flagSome) {
              this.$set(arr[i], "isCheck", false);
              this.$set(arr[i], "type", "half");
            } else {
              this.$set(arr[i], "isCheck", false);
              this.$set(arr[i], "type", "no");
            }
          }
          this.isAllCheck(children);
        }
      }
    },
  },
  watch: {
    dataAll: {
      handler(_new) {
         this.isAllCheck(_new);
      },
      deep: true,
    },
  },
};
</script>

<style scoped>
@font-face {
  font-family: "iconfont"; /* Project id 3048534 */
  src: url("//at.alicdn.com/t/font_3048534_c9xfx07miyu.woff2?t=1640313188998")
      format("woff2"),
    url("//at.alicdn.com/t/font_3048534_c9xfx07miyu.woff?t=1640313188998")
      format("woff"),
    url("//at.alicdn.com/t/font_3048534_c9xfx07miyu.ttf?t=1640313188998")
      format("truetype");
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-weiquanxuan:before {
  content: "\e606";
}

.icon-weiquanxuan1:before {
  content: "\e624";
}

.icon-choice-full:before {
  content: "\e9c5";
}

.icon-wuliukuaidiche:before {
  content: "\e600";
}

.icon-sanjiaoright:before {
  content: "\e6b7";
}
.treeNodeWrap {
  min-height: 35px;
  line-height: 35px;
  text-align: left;
  padding-left: 10px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
  width: 100%;
}
.handleToggle {
  min-width: 20px;
  height: 20px;
  margin-right: 10px;
  transition: all linear 0.3s;
  transform: rotate(0deg);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.rotate {
  transform: rotate(90deg);
}
.ul-enter-active,
.ul-leave-active {
  transition: all 0.5s;
}
.ul-enter,
.ul-leave-to {
  height: 0;
}

.wrapCheck {
  width: 15px;
  height: 15px;
  border: 1px solid #666;
  margin-right: 10px;
  margin-left: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}
.checkIcon {
  color: steelblue;
}
</style>
<style>
.treeNodeWrap span {
  display: block;
  width: 100%;
  height: auto;
}
</style>
